每天的專案會同步到 GitLab 上,可以前往 GitLab 查看,有興趣的朋友歡迎留言 or 來信討論,我的信箱是 nickchen1998@gmail.com。
今天我們要來串接資料查詢以及問答的部分,下面會分兩個區塊進行程式碼說明。
首先我們來看一下如何查詢資料,和前天爬文時相同,我們都要使用 MongoDBAtlasVectorSearch
這個 class 來進行查詢,這邊我們直接看一下下面這段程式碼:
...
if question and openai_key:
with st.chat_message("user"):
st.write(question)
with get_mongo_database() as database:
vector_store = MongoDBAtlasVectorSearch(
collection=Collection(database, name="illness"),
embedding=OpenAIEmbeddings(model="text-embedding-3-small", api_key=openai_key),
index_name="illness_refactor_question",
relevance_score_fn="cosine",
)
documents = vector_store.similarity_search(
query=question,
k=3,
pre_filter={"category": {"$eq": dataset_option}}
)
answer = get_answer(documents, question)
with st.chat_message("ai"):
st.write(answer)
...
vector_store.similarity_search
來進行查詢,並且設定 k=3
來取得前三個相似的問題。get_answer
函式則是用來取得最後的回答,這邊我們會將查詢到的資料以及使用者的問題一併傳入,讓它可以回傳最後的答案,下面我們會另外做說明。上面有提到 get_answer
,這邊就讓我們快速來看一下這段程式碼:
def get_answer(documents: List[Document], question: str) -> str:
system_prompt = SystemMessage(content="""
你是一個專業的醫生,下面是一些醫生針對過去類似症狀的回覆,請幫我根據這些回覆來針對患者現在的狀況做說明。
- 請勿使用文章以外的內容做回覆。
- 請使用繁體中文做回覆。
----
""")
for document in documents:
system_prompt.content += f"{document.metadata.get('refactor_answer')}\n"
system_prompt.content += "----\n"
llm = ChatOpenAI(
api_key=EnvSettings().OPENAI_API_KEY,
model_name="gpt-4o"
)
return llm.invoke([system_prompt, HumanMessage(content=question)]).content
SystemMessage
,這樣可以讓 AI 知道這些資料是用來做參考的。SystemMessage
以及使用者的問題一併傳入 ChatOpenAI
,這樣就可以取得最後的回答。下方圖片當中我們可以看到,我們在收到使用者的訊息後成功的查詢了資料並回答使用者的問題:
明天我們要將對話紀錄存下來讓使用者可以進行連續對話的功能!